import Node from './node';
import { getType, isNumber, log, draw } from '@/utils';

/**
 * 图片类
 */
export default class Image extends Node {
  className = 'Image'; // 类名
  constructor(config = {}) {
    super(config);
    this.src = config.src;
    this.image = config.image;
    // 图片裁剪 { x, y, w, h }
    this.clipping = config.clipping ?? null;
    // 固定宽高比
    this.lockAspectRatio = config.lockAspectRatio ?? true;
    // 是否根据图片原始尺寸自动设置宽高属性
    this.autoSize = config.autoSize ?? !isNumber(this.width);
    // 设置图片（优先src）
    this.setImage(this.src || this.image);
  }
  get widthRatio() {
    return this.width / this.clipping.w;
  }
  get heightRatio() {
    return this.height / this.clipping.h;
  }
  // 更新图片
  update() {
    const { image, autoSize } = this;
    if (!image) return;
    // 根据图片原始尺寸自动设置宽高属性
    if (autoSize) (this.width = image.width), (this.height = image.height);
    // 重绘
    this.stage?.draw();
  }
  // 绘制主要内容
  drawMain(ctx) {
    const { width, height, image, clipping } = this;
    // 图片未完全加载完成，不绘制
    if (!image?.complete) return;
    try {
      draw.image(ctx, { image, width, height, clipping });
    } catch (error) {
      log.error(this, '图片渲染出错！');
      draw.fillRect(ctx, { width, height, fillStyle: '#F1F1F1' });
      draw.text(ctx, {
        text: '图片加载失败',
        x: width / 2,
        y: height / 2,
        color: '#666',
        fontSize: 14,
        align: 'center',
      });
    }
  }
  /**
   * Methods
   */
  /**
   * 设置图片
   * @param {string | *} image
   * @returns
   */
  setImage(image) {
    if (!image) return;
    if (getType(image) === 'String') image = getImage(image);
    if (this.src !== image.src) this.src = image.src;
    this.image = image;
    // 浏览器已经下载完毕(cache) 将更新函数推迟到下一个事件循环中执行
    if (image.complete) {
      const timer = setTimeout(() => (this.update(), clearTimeout(timer)));
    }
    // 否则监听加载完毕
    else image.onload = () => this.update();
    // 图片加载出错
    image.onerror = () => this.update();
  }
}

/**
 * 根据 url 获取图片对象
 * @param {string} src
 */
export const getImage = (src) => {
  const image = new window.Image();
  // 允许图片和 canvas 跨源使用 https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_enabled_image
  image.crossOrigin = 'Anonymous';
  image.src = src;
  return image;
};
